#include "CTween.h"

Int32 CALLBACKTYPE GetBounceValue(
    /* [in] */ Int32 fromValue,
    /* [in] */ Int32 toValue,
    /* [in] */ Millisecond32 elaspedTime,
    /* [in] */ Millisecond32 durationTime,
    /* [in] */ EaseType easeType)
{
    double dx = toValue - fromValue;
    double delta = 0;
    double ratio = ((double)elaspedTime) / durationTime;

    switch (easeType) {
    case EaseType_In:
        delta = dx - GetBounceValue(0, toValue - fromValue,
                            (durationTime - elaspedTime), durationTime,
                            EaseType_Out);
        break;

    case EaseType_Out:
        if (ratio < (1 / 2.75)) {
            delta = dx * (7.5625 * ratio * ratio);
        }
        else if (ratio < (2 / 2.75)) {
            ratio -= 1.5 / 2.75;
            delta = dx * (7.5625 * ratio * ratio + 0.75);
        }
        else if (ratio < (2.5 / 2.75)) {
            ratio -= 2.25 / 2.75;
            delta = dx * (7.5625 * ratio * ratio + 0.9375);
        }
        else {
            ratio -= 2.625 / 2.75;
            delta = dx * (7.5625 * ratio * ratio + 0.984375);
        }

        break;

    case EaseType_InOut:
        if ((elaspedTime << 1) < durationTime) {
            delta = 0.5 * GetBounceValue(0, toValue - fromValue,
                                2 * elaspedTime, durationTime, EaseType_In);
        }
        else {
            delta = dx * 0.5 + 0.5 * GetBounceValue(0, toValue - fromValue,
                                2 * elaspedTime - durationTime, durationTime,
                                EaseType_Out);
        }

        break;

    default:
        assert(0);
    }

    return (Int32)(fromValue + delta);
}
